import Vue from 'vue'

/**
 * store实例在统一的new Vuex，只初始化一次
 */
class Store {
  constructor(options){
    // 和Vue实例保持同步
    // this.state = options.state || {}
    // 通过Vue实例来实现响应式，通过统一的get值来获取最新值
    this.vm = new Vue({
      data:{
        state: options.state
      }
    })
    let getters = options.getters || {}
    this.getters = {}
    // 属性名， 使用的是getters就会是重新获取
    Object.keys(getters).forEach(getterName => {
      Object.defineProperty(this.getters, getterName, {
        get: () => {
          // 执行返回的方法名，来执行方法，动态执行方法
          console.log('``````', getters[getterName]);
          return getters[getterName](options.state)
        }
      })
    })
    // mutations
    let mutations = options.mutations || {}
    this.mutations = {}
    Object.keys(mutations).forEach(mutationName => {
      // 这是个赋值操作
      this.mutations[mutationName] = (arg)=> {
        // 执行方法
        mutations[mutationName](this.state, arg)
      }
    })
  }
  // commit方法，供使用者调用修改方法
  commit(method, arg) {
    this.mutations[method](arg)
  }
  // es6 get语法：定义一个私有属性
  get state() {
    return this.vm.state
  }
}
let install = function (Vue) {
  // 注入组件选项
  Vue.mixin({
    beforeCreate(){
      if (this.$options && this.$options.store){ // 如果是根组件
        this.$store = this.$options.store
      }else { //如果是子组件
        this.$store = this.$parent && this.$parent.$store
      }
    }
  })
}

const Vuex = {
    Store,
    install
}

export default Vuex